home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / antipolix-2.0 / client.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-22  |  52.6 KB  |  2,166 lines

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <netinet/in.h>
  4. #include <time.h>
  5. #include <stdlib.h>
  6. #include <netdb.h>
  7. #include <stdio.h>
  8. #include <malloc.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11. #include <signal.h>
  12. #include <math.h>
  13.  
  14. #include <X11/X.h>
  15. #include <X11/Xlib.h>
  16. #include <X11/Xatom.h>
  17.  
  18. #include "messages.h"
  19. #include "creation.h"
  20. #include "game.h"
  21.  
  22. typedef struct {
  23.   char mesg[MESSAGE_BUF];
  24.   int from_who;
  25. } MesgStruct;
  26.  
  27. #define SABLIER_L 40
  28. #define SABLIER_H 300
  29. #define NB_DAMIERS 3
  30. int Max_Queues;  /* mis a jour par ReceiveQueueValues() */
  31. int QueueWait[MAX_QUEUES], QueueGood[MAX_QUEUES];
  32.  
  33. Parameters c_params;
  34.  
  35. double ALPHA=1.0;
  36. double LONG=450;
  37. double DIST=150;
  38. double COS_ALPHA[NB_DAMIERS], SIN_ALPHA[NB_DAMIERS];
  39. #define ECART_ALPHA 0.1
  40. #define LEFT_BORDER 50
  41. int tcase; /* LONG/SIZE_X */
  42.  
  43. #define _0_KEY    48
  44. #define _1_KEY    49
  45. #define _2_KEY    50
  46. #define _3_KEY    51
  47. #define _4_KEY    52
  48. #define _5_KEY    53
  49. #define _6_KEY    54
  50. #define _7_KEY    55
  51. #define _8_KEY    56
  52. #define _9_KEY    57
  53. #define U_KEY        117
  54. #define V_KEY        118
  55. #define J_KEY        106
  56. #define O_KEY        111
  57. #define P_KEY        112
  58. #define FLECHE_H    U_KEY
  59. #define FLECHE_D    P_KEY
  60. #define FLECHE_B     J_KEY
  61. #define FLECHE_G    O_KEY
  62. #define A_KEY         97
  63. #define C_KEY         99
  64. #define T_KEY         116
  65. #define F_KEY        102
  66. #define H_KEY         104
  67. #define M_KEY        109
  68. #define N_KEY        110
  69. #define Q_KEY        113
  70. #define BigQ_KEY    81        
  71. #define R_KEY        114
  72. #define I_KEY        105
  73. #define SPACE_KEY    32
  74. #define BACK_SPACE    65288
  75. #define DEL_KEY            65535
  76. #define RETURN_KEY     65293
  77. #define _MAX_ASCII_    128
  78.  
  79.  
  80. /* ----------------------- INTERFACE ------------------------ */
  81. Display *DISPLAY;
  82. Window WinPlx, WinPlayers, WinLogin, WinWait, WinMessages;
  83. int WinSizeX, WinSizeY;
  84. GC Sablier_gc, MidLines_gc, Lines_gc, MiniLines_gc, Selection_gc, Black_gc, Draw_gc[MAX_USERS], 
  85.    Caract_gc;
  86. GC Login_gc, Title_gc;
  87. XWindowAttributes XAttr;
  88.  
  89. /* ----------- messages --------- */
  90. int NB_MESSAGES, MesgX=15, MesgWidth, WIN_MESG_H=200, WIN_MESG_W=400;
  91. MesgStruct *Messages=NULL;
  92. #define MESG_ECART 15
  93.  
  94. /* ----------- login ------------ */
  95. #define WIN_LOGIN_WIDTH 500
  96. char M_buf[3][255];
  97. int LOGIN_Y[3];
  98. #define MAX_MOTD_LINES 30
  99. static char Motd[MAX_MOTD_LINES][MESSAGE_BUF];
  100. static int nb_motd_lines;
  101. int LargeurCase;
  102.  
  103. /* ----------- coordonnees des cases ------------- */
  104. typedef struct {
  105.   int x1;
  106.   int y1;
  107.   int x2;
  108.   int y2;
  109.   int x3;
  110.   int y3;
  111.   int x4;
  112.   int y4;
  113. } Point;
  114.  
  115. Point **Coord[NB_DAMIERS];
  116.  
  117. /* ---------------------------------------------------------- */
  118.  
  119. int Old_Forteresses=0, Forteresses=0, Old_Chef=0, Chef=0; /* pour le placement de depart */
  120.  
  121. OneMovement Movement[NB_MOVES];
  122. int CurrentMove;
  123.  
  124. int CurrentPlx=0, CurrentView=0, CurrentMode=0;
  125. int cut_nbp, cut_nbx, cut_nby; /* nb de plx, taille en x et en y du tranchage courant */
  126.  
  127. char *ConnectionClosed="Server seems to have closed connection... Waiting...\n";
  128. char *ConnectionError="Server does not respond any more...\n";
  129.  
  130. char Names[MAX_USERS][NAME_BUF], Email[MAX_USERS][EMAILENGTH];
  131. int IsAlive[MAX_USERS], Score[MAX_USERS];
  132. int nbplayers;
  133.  
  134. void d2to3d(int x, int y, int *X, int *Y, double Cos, double Sin)
  135. {
  136.   double s1=(double)y*Sin, c1=(double)y*Cos;
  137.   /* *Y=s1-s1/(1.0+DIST/(c1)); */
  138.   *Y=DIST*s1/(DIST+c1);
  139.   /* *X=x+(LONG/2.0 - (double)x)/(1.0 + DIST/c1);*/
  140.   *X=((double)x*DIST+LONG/2.0*c1)/(c1+DIST);
  141. }
  142.  
  143. void d3to2di(int X, int Y, int *x, int *y, double Cos, double Sin)
  144. {
  145.   int ax, ay;
  146.   ax=Y*(X-LONG/2.0)/(DIST*Sin/Cos-Y)+X;
  147.   ay=Y*DIST/(DIST*Sin-Y*Cos);
  148.   *x=ax/tcase;
  149.   *y=ay/tcase;
  150. }
  151.   
  152. void Real2View(int p, int x, int y, int *P, int *X, int *Y, int V_Mode)
  153. {
  154.   if (V_Mode==0)  /* mode de vue ("tranchage") normal des plateaux */
  155.     {
  156.       *P=p;
  157.       if (!CurrentView)
  158.     {
  159.       *X=x;
  160.       *Y=y;
  161.       return;
  162.     }
  163.       switch(CurrentView)
  164.     {
  165.     case 1:
  166.       *X=y;
  167.       *Y=cut_nby-x-1;
  168.       break;
  169.     case 2:
  170.       *X=cut_nbx-x-1;
  171.       *Y=cut_nby-y-1;
  172.       break;
  173.     case 3:
  174.       *X=cut_nbx-y-1;
  175.       *Y=x;
  176.       break;
  177.     }
  178.       return;
  179.     }
  180.   else if (V_Mode==1)
  181.     {
  182.       int m_p, m_x, m_y;
  183.       
  184.       m_p=y;
  185.       m_x=x;
  186.       m_y=p;
  187.       Real2View(m_p, m_x, m_y, P, X, Y, 0);
  188.     }
  189.   else if (V_Mode==2)
  190.     {
  191.       int m_p, m_x, m_y;
  192.       
  193.       m_p=x;
  194.       m_x=c_params.SIZE_X-y-1;
  195.       m_y=p;
  196.       Real2View(m_p, m_x, m_y, P, X, Y, 0);
  197.     }
  198. }
  199.  
  200. void View2Real(int P, int X, int Y, int *p, int *x, int *y, int V_Mode)
  201. {
  202.   if (V_Mode==0)  /* mode de vue normal des plateaux ("tranchage") */
  203.     {
  204.       *p=P;
  205.       if (!CurrentView)
  206.     {
  207.       *x=X;
  208.       *y=Y;
  209.       return;
  210.     }
  211.       switch(CurrentView)
  212.     {
  213.     case 1:
  214.       *y=X;
  215.       *x=cut_nby-Y-1;
  216.       break;
  217.     case 2:
  218.       *x=cut_nbx-X-1;
  219.       *y=cut_nby-Y-1;
  220.       break;
  221.     case 3:
  222.       *y=cut_nbx-X-1;
  223.       *x=Y;
  224.       break;
  225.     }
  226.       return;
  227.     }
  228.   else if (V_Mode==1)
  229.     {
  230.       int m_p, m_x, m_y;
  231.       
  232.       View2Real(P, X, Y, &m_p, &m_x, &m_y, 0);
  233.       *p=m_y;
  234.       *x=m_x;
  235.       *y=m_p;
  236.     }
  237.   else if (V_Mode==2)
  238.     {
  239.       int m_p, m_x, m_y;
  240.       
  241.       View2Real(P, X, Y, &m_p, &m_x, &m_y, 0);
  242.       *p=m_y;
  243.       *x=m_p;
  244.       *y=c_params.SIZE_X-m_x-1;
  245.     }
  246. }
  247.  
  248.  
  249. void AfficheLegendeSablier(char *legende)
  250. {
  251.   XClearArea(DISPLAY, WinPlx, WinSizeX+SABLIER_L/2, 100+SABLIER_H, 50, 50, False);
  252.   XDrawString(DISPLAY, WinPlx, MidLines_gc, WinSizeX+SABLIER_L/2, 100+SABLIER_H+20, 
  253.           legende, strlen(legende));
  254. }
  255.  
  256.  
  257. void MiseAJourDuSablier(int Valeur)
  258. {
  259.   int niv;
  260.   XClearArea(DISPLAY, WinPlx, WinSizeX+SABLIER_L/2, 100, SABLIER_L, SABLIER_H, False);
  261.   if (Valeur>SABLIER_H)
  262.     niv=SABLIER_H;
  263.   else
  264.     niv=Valeur;
  265.    XFillRectangle(DISPLAY, WinPlx, Sablier_gc, WinSizeX+SABLIER_L/2, 100+SABLIER_H-niv, 
  266.           SABLIER_L, niv);
  267.   XFlush(DISPLAY);
  268. }
  269.  
  270. GC CreeXorGC(Window TheWindow, char *TheColor, int LineWidth)
  271. {
  272.   XGCValues gc_values;
  273.   GC gc;
  274.   XColor ColorExact, ColorScreen;
  275.  
  276.   XAllocNamedColor(DISPLAY, DefaultColormap(DISPLAY, DefaultScreen(DISPLAY)), TheColor,
  277.                    &ColorScreen, &ColorExact);
  278.   gc_values.foreground = ColorScreen.pixel;
  279.   gc_values.line_width = LineWidth;
  280.   gc_values.function = GXxor;
  281.   gc = XCreateGC(DISPLAY, TheWindow, (GCBackground|GCForeground|GCLineWidth|GCFunction), 
  282.          &gc_values);
  283.   return gc;
  284. }
  285.  
  286.  
  287. GC CreeGC(Window TheWindow, char *TheColor, int LineWidth)
  288. {
  289.   XGCValues gc_values;
  290.   GC gc;
  291.   XColor ColorExact, ColorScreen;
  292.  
  293.   XAllocNamedColor(DISPLAY, DefaultColormap(DISPLAY, DefaultScreen(DISPLAY)), TheColor,
  294.                    &ColorScreen, &ColorExact);
  295.   gc_values.foreground = ColorScreen.pixel;
  296.   gc_values.line_width = LineWidth;
  297.   gc = XCreateGC(DISPLAY, TheWindow, (GCBackground|GCForeground|GCLineWidth), &gc_values);
  298.   return gc;
  299. }
  300.  
  301. GC CreeTitleGC(Window TheWindow, char *TheColor)
  302. {
  303.   XGCValues gc_values;
  304.   GC gc;
  305.   XColor ColorExact, ColorScreen;
  306.   XFontStruct *xfs;
  307.  
  308.   xfs = XLoadQueryFont(DISPLAY, "-*-symbol-*-*-*-*-*-450-*-*-*-*-*-*");
  309.   XAllocNamedColor(DISPLAY, DefaultColormap(DISPLAY, DefaultScreen(DISPLAY)), TheColor,
  310.                    &ColorScreen, &ColorExact);
  311.   gc_values.foreground = ColorScreen.pixel;
  312.   gc_values.font=xfs->fid;
  313.   gc = XCreateGC(DISPLAY, TheWindow, 
  314.          (GCBackground|GCForeground|GCFont), &gc_values);
  315.   return gc;
  316. }
  317.  
  318. void CreationDesGC(int nbniveaux)
  319. {
  320.   int j, NBCOLORS=10;
  321.   char *Couleurs[]={"red", "goldenrod1", "white", "seagreen3", "blue2", "slate gray", 
  322.               "MediumOrchid2", "burlywood4", "deep pink", "forest green"};
  323.   /* le noir doit rester en 0 et le blanc en 2 ! */
  324.  
  325.   for (j=0; j<NBCOLORS; j++)
  326.     Draw_gc[j]=CreeGC(WinPlx, Couleurs[j], 1);
  327.  
  328.   Lines_gc=CreeGC(WinPlx, "steelblue4", 1);
  329.   MidLines_gc=CreeGC(WinPlx, "wheat4", 1);
  330.   MiniLines_gc=CreeGC(WinPlx, "wheat1", 1);
  331.   Caract_gc=CreeXorGC(WinPlx, "wheat1", 1);
  332.   Selection_gc=CreeGC(WinPlx, "wheat1", 1);
  333.   Sablier_gc=CreeGC(WinPlx, "steelblue4", 1);
  334.   Black_gc=CreeGC(WinPlx, "black", 1);
  335. }
  336.  
  337.  
  338. void CalculeCosSin()
  339. {
  340.   COS_ALPHA[0]=cos(ALPHA);
  341.   SIN_ALPHA[0]=sin(ALPHA);
  342.   COS_ALPHA[1]=cos(ALPHA-ECART_ALPHA);
  343.   SIN_ALPHA[1]=sin(ALPHA-ECART_ALPHA);
  344.   COS_ALPHA[2]=cos(ALPHA-2*ECART_ALPHA);
  345.   SIN_ALPHA[2]=sin(ALPHA-2*ECART_ALPHA);
  346. }
  347.  
  348. void InitCoords()
  349. {
  350.   int p, x, y, i, j;
  351.   double Cos, Sin;
  352.   
  353.   for (i=0; i<NB_DAMIERS; i++)
  354.     {
  355.       Coord[i]=malloc(c_params.SIZE_X*sizeof(Point *));
  356.       for (j=0; j<c_params.SIZE_X; j++)
  357.     Coord[i][j]=malloc(c_params.SIZE_X*sizeof(Point));
  358.     }
  359.  
  360.   for (p=0; p<NB_DAMIERS; p++)
  361.     {
  362.       Cos=COS_ALPHA[p];
  363.       Sin=SIN_ALPHA[p];
  364.       for (x=0; x<c_params.SIZE_X; x++)
  365.     for (y=0; y<c_params.SIZE_X; y++)
  366.       {
  367.         d2to3d(x*tcase, y*tcase, &(Coord[p][x][y].x1), &(Coord[p][x][y].y1), Cos, Sin);
  368.         d2to3d(x*tcase, (y+1)*tcase, &(Coord[p][x][y].x2), &(Coord[p][x][y].y2), Cos, Sin);
  369.         d2to3d((x+1)*tcase, (y+1)*tcase, &(Coord[p][x][y].x3), &(Coord[p][x][y].y3), Cos, Sin);
  370.         d2to3d((x+1)*tcase, y*tcase, &(Coord[p][x][y].x4), &(Coord[p][x][y].y4), Cos, Sin);
  371.       }
  372.     }
  373. }
  374.  
  375. void InitCutVars(int Mode)
  376. /* init. les variables definissant les plateaux pour le tranchage courant */
  377. {
  378.   switch(Mode)
  379.     {
  380.     case 0:
  381.       cut_nbp=c_params.SIZE_Z;
  382.       cut_nbx=cut_nby=c_params.SIZE_X;
  383.       tcase=LONG/cut_nbx;  /* mise a jour */
  384.       break;
  385.     case 1:
  386.       switch(CurrentView)
  387.     {
  388.     case 0:
  389.     case 2:
  390.       cut_nbp=cut_nbx=c_params.SIZE_X;
  391.       cut_nby=c_params.SIZE_Z;
  392.       break;
  393.     case 1:
  394.     case 3:
  395.       cut_nbp=cut_nby=c_params.SIZE_X;
  396.       cut_nbx=c_params.SIZE_Z;
  397.       break;
  398.     }
  399.       tcase=LONG/cut_nbx;  /* mise a jour */
  400.       break;
  401.     case 2:
  402.       switch(CurrentView)
  403.     {
  404.     case 0:
  405.     case 2:
  406.       cut_nbp=cut_nbx=c_params.SIZE_X;
  407.       cut_nby=c_params.SIZE_Z;
  408.       break;
  409.     case 1:
  410.     case 3:
  411.       cut_nbp=cut_nby=c_params.SIZE_X;
  412.       cut_nbx=c_params.SIZE_Z;
  413.       break;
  414.     }
  415.       tcase=LONG/cut_nbx;  /* mise a jour */
  416.       break;
  417.     }
  418.   InitCoords(); /* pour prendre en compte le changement de "tcase" */
  419. }
  420.  
  421. void ReallocMessagesTable()
  422. {
  423.   static int memo=0;
  424.  
  425.   if (memo==NB_MESSAGES)
  426.     return;
  427.   if (Messages==NULL)
  428.     Messages=malloc(NB_MESSAGES*sizeof(MesgStruct));
  429.   else
  430.     Messages=realloc(Messages, NB_MESSAGES*sizeof(MesgStruct));
  431.   memo=NB_MESSAGES;
  432. }
  433.  
  434. void InitVariables()
  435. {
  436.   int i;
  437.  
  438.   tcase=LONG/c_params.SIZE_X;
  439.   WinSizeX=LONG+100;
  440.   WinSizeY=3*LONG/2+20;
  441.  
  442.   MesgWidth=WIN_MESG_W;
  443.   NB_MESSAGES=WIN_MESG_H/MESG_ECART-1;
  444.   ReallocMessagesTable(NB_MESSAGES);
  445.  
  446.   CalculeCosSin();
  447.   InitCoords();
  448.  
  449.   CurrentMode=0; /* tranchage */
  450.   InitCutVars(CurrentMode);
  451.  
  452.   for (i=0; i<NB_MESSAGES; i++)
  453.     strcpy(Messages[i].mesg, "");
  454.  
  455.   for (i=0; i<3; i++)
  456.     LOGIN_Y[i]=170+30*i;
  457. }
  458.  
  459. void CreationDesFenetres(int NbNiveaux)
  460. {
  461.   int i;
  462.   
  463.   WinPlx=XCreateSimpleWindow(DISPLAY, RootWindow(DISPLAY, DefaultScreen(DISPLAY)), 0, 0,
  464.                  WinSizeX+2*SABLIER_L, WinSizeY, 2, 0, 
  465.                  BlackPixel(DISPLAY, DefaultScreen(DISPLAY)));
  466.   XSelectInput(DISPLAY, WinPlx, ButtonPressMask|ButtonReleaseMask|KeyPressMask|ExposureMask);
  467.   XStoreName(DISPLAY, WinPlx, "AntipoliX");
  468.   XMapWindow(DISPLAY, WinPlx);
  469.  
  470.   WinPlayers=XCreateSimpleWindow(DISPLAY, RootWindow(DISPLAY, DefaultScreen(DISPLAY)), 0, 0, 
  471.                  250, 40+20*nbplayers, 2, 0, 
  472.                  BlackPixel(DISPLAY, DefaultScreen(DISPLAY)));
  473.   XSelectInput(DISPLAY, WinPlayers, ButtonPressMask|ButtonReleaseMask|KeyPressMask|ExposureMask);
  474.   XStoreName(DISPLAY, WinPlayers, "Players");
  475.   XMapWindow(DISPLAY, WinPlayers);
  476.  
  477.   WinMessages=XCreateSimpleWindow(DISPLAY, RootWindow(DISPLAY, DefaultScreen(DISPLAY)), 0, 0, 
  478.                   WIN_MESG_W, WIN_MESG_H, 2, 0, 
  479.                   BlackPixel(DISPLAY, DefaultScreen(DISPLAY)));
  480.   XSelectInput(DISPLAY, WinMessages, KeyPressMask|ExposureMask);
  481.   XStoreName(DISPLAY, WinMessages, "Messages");
  482.   XMapWindow(DISPLAY, WinMessages);
  483.  
  484.   XFlush(DISPLAY);
  485. }
  486.                   
  487. void LoginWindowCreation()
  488. {
  489.   if ((DISPLAY = XOpenDisplay(NULL)) == NULL)
  490.     {
  491.       printf("** Can't open display. Ciao !\n");
  492.       exit(-1);
  493.     }
  494.  
  495.   WinLogin=XCreateSimpleWindow(DISPLAY, RootWindow(DISPLAY, DefaultScreen(DISPLAY)), 0, 0, 
  496.                    WIN_LOGIN_WIDTH, 800, 2, 0, 
  497.                    BlackPixel(DISPLAY, DefaultScreen(DISPLAY)));
  498.   XSelectInput(DISPLAY, WinLogin, ButtonPressMask|ButtonReleaseMask|KeyPressMask|ExposureMask);
  499.   XStoreName(DISPLAY, WinLogin, "AntipoliX");
  500.   XMapWindow(DISPLAY, WinLogin);
  501.  
  502.   WinWait=XCreateSimpleWindow(DISPLAY, RootWindow(DISPLAY, DefaultScreen(DISPLAY)), 0, 0, 
  503.                   200, 70, 2, 0, 
  504.                   BlackPixel(DISPLAY, DefaultScreen(DISPLAY)));
  505.   XSelectInput(DISPLAY, WinWait, ButtonPressMask|KeyPressMask|ExposureMask);
  506.   XStoreName(DISPLAY, WinWait, "AntipoliX");
  507. }
  508.  
  509. void DessineInvisible(int p, int x, int y)
  510. {
  511.   Point P=Coord[p-CurrentPlx][x][y];
  512.   static XPoint XP[5];
  513.   int bx, by;
  514.   
  515.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-p+CurrentPlx)/2;
  516.   
  517.   XP[0].x=bx+P.x1;
  518.   XP[0].y=by-P.y1;
  519.   XP[1].x=bx+P.x2;
  520.   XP[1].y=by-P.y2;
  521.   XP[2].x=bx+P.x3;
  522.   XP[2].y=by-P.y3;
  523.   XP[3].x=bx+P.x4;
  524.   XP[3].y=by-P.y4;
  525.   XFillPolygon(DISPLAY, WinPlx, Lines_gc, XP, 4, Convex, CoordModeOrigin);
  526. }
  527.  
  528. void DessineChef(int p, int x, int y)
  529. {
  530.   Point P=Coord[p-CurrentPlx][x][y];
  531.   static XPoint XP[5];
  532.   int vx, vy, bx, by;
  533.   
  534.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-p+CurrentPlx)/2;
  535.  
  536.   vx=(P.x4-P.x1)/7;
  537.   vy=(P.y2-P.y1)/7;
  538.   XP[0].x=bx+P.x1+7*vx/3;
  539.   XP[0].y=by-P.y1-vy;
  540.  
  541.   XP[1].x=bx+P.x4-7*vx/3;
  542.   XP[1].y=by-P.y1-vy;
  543.  
  544.   XP[2].x=bx+(P.x3+P.x2)/2;
  545.   XP[2].y=by-P.y2+vy;
  546.  
  547.   XP[3].x=XP[0].x;
  548.   XP[3].y=XP[0].y;
  549.   XDrawLines(DISPLAY, WinPlx, Caract_gc, XP, 4, CoordModeOrigin);
  550. }
  551.  
  552. void DessineTeleport(int p, int x, int y)
  553. {
  554.   Point P=Coord[p-CurrentPlx][x][y];
  555.   static XPoint XP[5];
  556.   int vx, vy, bx, by;
  557.   
  558.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-p+CurrentPlx)/2;
  559.   vx=(P.x3-P.x2)/3;
  560.   vy=(P.y2-P.y1)/3;
  561.   XP[0].x=bx+P.x2+2;
  562.   XP[0].y=by-P.y2+2;
  563.   XP[1].x=bx+P.x2+2+vx;
  564.   XP[1].y=by-P.y2+2;
  565.   XP[2].x=bx+P.x1+2*(P.x2-P.x1)/3+2;
  566.   XP[2].y=by-P.y3+2+vy;
  567.   XFillPolygon(DISPLAY, WinPlx, MiniLines_gc, XP, 3, Convex, CoordModeOrigin);
  568. }
  569.  
  570. void DessineCaract(int p, int x, int y, int caract)
  571. {  
  572.   switch(caract)
  573.     {
  574.     case INVISIBLE:
  575.       DessineInvisible(p, x, y);
  576.       break;
  577.     case TELEPORT:
  578.       DessineTeleport(p, x, y);
  579.       break;
  580.     case CHEF:
  581.       DessineChef(p, x, y);
  582.       break;
  583.     case NORMAL:
  584.       break;
  585.     }
  586. }
  587.  
  588. void DessineCase(int P, int X, int Y, GC *gc)
  589. /* Recoit les coordonnees REELLES de la case */
  590. {
  591.   int x1, y1, x2, y2, x3, y3, x4, y4, bx, by, p, pview, xview, yview;
  592.   double Cos, Sin;
  593.   Point PP;
  594.  
  595.   Real2View(P, X, Y, &pview, &xview, &yview, CurrentMode);
  596.   p=pview-CurrentPlx;
  597.   if (p>=0 && p<NB_DAMIERS)  /* verification qu'on est dans le champ de vision */
  598.     PP=Coord[p][xview][yview];
  599.   else
  600.     return;  /* on est dans le cas de l'AfficheMovement d'un mouvement hors-champ */
  601.   bx=50; by=(LONG)*(NB_DAMIERS-p)/2;
  602.  
  603.   XDrawLine(DISPLAY, WinPlx, *gc, bx+PP.x1, by-PP.y1, bx+PP.x2, by-PP.y2);
  604.   XDrawLine(DISPLAY, WinPlx, *gc, bx+PP.x2, by-PP.y2, bx+PP.x3, by-PP.y3);
  605.   XDrawLine(DISPLAY, WinPlx, *gc, bx+PP.x3, by-PP.y3, bx+PP.x4, by-PP.y4);
  606.   XDrawLine(DISPLAY, WinPlx, *gc, bx+PP.x4, by-PP.y4, bx+PP.x1, by-PP.y1);
  607. }
  608.  
  609. void DessineArmee(int p, int x, int y, int couleur, int caract)
  610. {
  611.   Point P=Coord[p-CurrentPlx][x][y];
  612.   static XPoint XP[5];
  613.   int vx, vy, bx, by;
  614.   
  615.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-p+CurrentPlx)/2;
  616.   if (caract==INVISIBLE)
  617.     DessineCaract(p, x, y, caract);
  618.   vx=(P.x4-P.x1)/7;
  619.   vy=(P.y2-P.y1)/7;
  620.   XP[0].x=bx+P.x1+vx;
  621.   XP[0].y=by-P.y1-vy;
  622.   XP[1].x=bx+P.x1+3*vx;
  623.   XP[1].y=by-P.y1-vy;
  624.   XP[2].x=bx+P.x3-2;
  625.   XP[2].y=by-P.y3+vy;
  626.   XFillPolygon(DISPLAY, WinPlx, Draw_gc[couleur], XP, 3, Convex, CoordModeOrigin);
  627.   XP[0].x=bx+P.x4-vx;
  628.   XP[0].y=by-P.y1-vy;
  629.   XP[1].x=bx+P.x4-3*vx;
  630.   XP[1].y=by-P.y1-vy;
  631.   XP[2].x=bx+P.x2+2;
  632.   XP[2].y=by-P.y2+vy;
  633.   XFillPolygon(DISPLAY, WinPlx, Draw_gc[couleur], XP, 3, Convex, CoordModeOrigin);
  634.   if (caract!=INVISIBLE)
  635.     DessineCaract(p, x, y, caract);
  636. }
  637.  
  638. void DessineHovercraft(int p, int x, int y, int couleur, int caract)
  639. {
  640.   Point P=Coord[p-CurrentPlx][x][y];
  641.   static XPoint XP[5];
  642.   int vx, vy, bx, by;
  643.   
  644.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-p+CurrentPlx)/2;
  645.  
  646.   if (caract==INVISIBLE)
  647.     DessineCaract(p, x, y, caract);
  648.   vx=(P.x4-P.x1)/7;
  649.   vy=(P.y2-P.y1)/7;
  650.   XP[0].x=bx+P.x1+vx;
  651.   XP[0].y=by-P.y1-vy;
  652.   XP[1].x=bx+P.x1+2*vx;
  653.   XP[1].y=by-P.y1-vy;
  654.   XP[2].x=bx+(P.x3+P.x2)/2;
  655.   XP[2].y=by-P.y3+vy;
  656.   XFillPolygon(DISPLAY, WinPlx, Draw_gc[couleur], XP, 3, Convex, CoordModeOrigin);
  657.   XP[0].x=bx+P.x4-vx;
  658.   XP[0].y=by-P.y1-vy;
  659.   XP[1].x=bx+P.x4-2*vx;
  660.   XP[1].y=by-P.y1-vy;
  661.   XP[2].x=bx+(P.x3+P.x2)/2;
  662.   XP[2].y=by-P.y2+vy;
  663.   XFillPolygon(DISPLAY, WinPlx, Draw_gc[couleur], XP, 3, Convex, CoordModeOrigin);
  664.   XDrawLine(DISPLAY, WinPlx, Draw_gc[couleur], bx+P.x1+2*vx, by-P.y1-vy, bx+P.x4-2*vx, by-P.y1-vy);
  665.   if (caract!=INVISIBLE)
  666.     DessineCaract(p, x, y, caract);
  667. }
  668.  
  669. void DessineForteresse(int p, int x, int y, int couleur, int caract)
  670. {
  671.   Point P=Coord[p-CurrentPlx][x][y];
  672.   static XPoint XP[5];
  673.   int vx, vy, bx, by;
  674.   GC gc;
  675.   
  676.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-p+CurrentPlx)/2;
  677.   
  678.   if (couleur==CASE_OCCUPEE)
  679.     gc=Caract_gc;
  680.   else
  681.     {
  682.       gc=Draw_gc[couleur];
  683.       if (caract==INVISIBLE)
  684.     DessineCaract(p, x, y, caract);
  685.     }
  686.   vx=(P.x4-P.x1)/7;
  687.   vy=(P.y2-P.y1)/7;
  688.   XP[0].x=bx+P.x1+vx;
  689.   XP[0].y=by-P.y1-vy;
  690.   XP[1].x=bx+P.x4-vx;
  691.   XP[1].y=by-P.y1-vy;
  692.   XP[2].x=bx+P.x2+4*(P.x3-P.x2)/5;
  693.   XP[2].y=by-P.y2+vy;
  694.   XP[3].x=bx+P.x2+(P.x3-P.x2)/5;
  695.   XP[3].y=by-P.y2+vy;
  696.   XFillPolygon(DISPLAY, WinPlx, gc, XP, 4, Convex, CoordModeOrigin);
  697.   if (caract!=INVISIBLE)
  698.     DessineCaract(p, x, y, caract);
  699. }
  700.  
  701. void EffaceCase(int real_p, int real_x, int real_y, int p, int x, int y)
  702. /* recoit les coordonnees REELLES (real_p, ...) et RELATIVES (p, x, y) de la case */
  703. {
  704.   Point P=Coord[p-CurrentPlx][x][y];
  705.   static XPoint XP[5];
  706.   int bx, by;
  707.   
  708.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-p+CurrentPlx)/2;
  709.  
  710.   XP[0].x=bx+P.x1;
  711.   XP[0].y=by-P.y1;
  712.   XP[1].x=bx+P.x2;
  713.   XP[1].y=by-P.y2;
  714.   XP[2].x=bx+P.x3;
  715.   XP[2].y=by-P.y3;
  716.   XP[3].x=bx+P.x4;
  717.   XP[3].y=by-P.y4;
  718.   XFillPolygon(DISPLAY, WinPlx, Black_gc, XP, 4, Convex, CoordModeOrigin);
  719.   DessineCase(real_p, real_x, real_y, &Lines_gc);
  720. }
  721.  
  722. void DessinePiece(int couleur, int type, int caract, int p, int x, int y)
  723. /* Recoit les coordonnees REELLES de la piece */
  724. {
  725.   static int P, X, Y;
  726.   Real2View(p, x, y, &P, &X, &Y, CurrentMode);
  727.   EffaceCase(p, x, y, P, X, Y);
  728.   switch(type)
  729.     {
  730.     case CASE_VIDE:
  731.       break;
  732.     case ARMEE:
  733.       DessineArmee(P, X, Y, couleur, caract);
  734.       break;
  735.     case HOVERCRAFT:
  736.       DessineHovercraft(P, X, Y, couleur, caract);
  737.       break;
  738.     case FORTERESSE:
  739.       DessineForteresse(P, X, Y, couleur, caract);
  740.       break;
  741.     }
  742. }
  743.  
  744. void FastDessinePiece(int couleur, int type, int caract, int p, int x, int y)
  745. /* Recoit les coordonnees REELLES de la piece */
  746. {
  747.   static int P, X, Y;
  748.   Real2View(p, x, y, &P, &X, &Y, CurrentMode);
  749.   if (couleur==CASE_OCCUPEE)
  750.     {
  751.       DessineForteresse(P, X, Y, CASE_OCCUPEE, NORMAL);
  752.       return;
  753.     }
  754.   switch(type)
  755.     {
  756.     case CASE_VIDE:
  757.       break;
  758.     case ARMEE:
  759.       DessineArmee(P, X, Y, couleur, caract);
  760.       break;
  761.     case HOVERCRAFT:
  762.       DessineHovercraft(P, X, Y, couleur, caract);
  763.       break;
  764.     case FORTERESSE:
  765.       DessineForteresse(P, X, Y, couleur, caract);
  766.       break;
  767.     }
  768. }
  769.  
  770.  
  771.  
  772. void DessineMidLines(int RelatPlx)
  773. /* recoit le numero de plateau a l'ecran (0 - NB_DAMIERS) */
  774. {
  775.   double Cos, Sin;
  776.   int bx, by, i, X1, Y1, X2, Y2;
  777.  
  778.   Cos=COS_ALPHA[RelatPlx];
  779.   Sin=SIN_ALPHA[RelatPlx];
  780.   bx=LEFT_BORDER; by=(LONG)*(NB_DAMIERS-RelatPlx)/2;
  781.   i=cut_nbx/2;
  782.   d2to3d(i*tcase, 0, &X1, &Y1, Cos, Sin);
  783.   d2to3d(i*tcase, cut_nby*tcase, &X2, &Y2, Cos, Sin);
  784.   XDrawLine(DISPLAY, WinPlx, MidLines_gc, bx+X1, by-Y1, bx+X2, by-Y2);
  785.   i=cut_nby/2;
  786.   d2to3d(0, i*tcase, &X1, &Y1, Cos, Sin);
  787.   d2to3d(cut_nbx*tcase, i*tcase, &X2, &Y2, Cos, Sin);
  788.   XDrawLine(DISPLAY, WinPlx, MidLines_gc, bx+X1, by-Y1, bx+X2, by-Y2);
  789. }
  790.  
  791.  
  792. void CreationDesDamiers(Univers *U)
  793. {
  794.   int i, j, bx, by, X1, Y1, X2, Y2;
  795.   double Cos, Sin;
  796.   GC gc;
  797.  
  798.   XClearArea(DISPLAY, WinPlx, 0, 0, WinSizeX, WinSizeY, False);
  799.   for (j=0; j<NB_DAMIERS && j<cut_nbp; j++)
  800.     {
  801.       Cos=COS_ALPHA[NB_DAMIERS-j-1];
  802.       Sin=SIN_ALPHA[NB_DAMIERS-j-1];
  803.       bx=LEFT_BORDER; by=(LONG)*(j+1)/2;
  804.       for (i=0; i<cut_nby+1; i++)
  805.     {
  806.       if (i==cut_nby/2)
  807.         gc=MidLines_gc;
  808.       else
  809.         gc=Lines_gc;
  810.       d2to3d(0, i*tcase, &X1, &Y1, Cos, Sin);
  811.       d2to3d(cut_nbx*tcase, i*tcase, &X2, &Y2, Cos, Sin);
  812.       XDrawLine(DISPLAY, WinPlx, gc, bx+X1, by-Y1, bx+X2, by-Y2);
  813.     }
  814.       
  815.       for (i=0; i<cut_nbx+1; i++)
  816.     {
  817.       if (i==cut_nbx/2)
  818.         gc=MidLines_gc;
  819.       else
  820.         gc=Lines_gc;
  821.       d2to3d(i*tcase, 0, &X1, &Y1, Cos, Sin);
  822.       d2to3d(i*tcase, cut_nby*tcase, &X2, &Y2, Cos, Sin);
  823.       XDrawLine(DISPLAY, WinPlx, gc, bx+X1, by-Y1, bx+X2, by-Y2);
  824.     }
  825.       DessineMidLines(NB_DAMIERS-j-1);
  826.     }
  827. }
  828.  
  829.  
  830. void CreationDesMiniPlx(Univers *U)
  831. {
  832.   int j;
  833.   GC gc;
  834.   
  835.   XClearArea(DISPLAY, WinPlx, WinSizeX+SABLIER_L/2, 100+SABLIER_H+50, 
  836.          SABLIER_L, 150, False);
  837.   for (j=0; j<cut_nbp; j++)
  838.     {
  839.       if (j>=CurrentPlx && j<CurrentPlx+NB_DAMIERS)
  840.     gc=MiniLines_gc;
  841.       else
  842.     gc=Lines_gc;
  843.       XDrawLine(DISPLAY, WinPlx, gc, WinSizeX+SABLIER_L/2, 300+SABLIER_H-15*j, 
  844.         WinSizeX+3*SABLIER_L/2, 300+SABLIER_H-15*j);
  845.     }
  846. }
  847.  
  848.  
  849. void EffaceMessages()
  850. {
  851.   /* XClearArea(DISPLAY, WinPlx, MesgX, 0MesgY[0]-MESG_ECART, MesgWidth, 
  852.          (NB_MESSAGES+1)*MESG_ECART, False); */
  853.   XClearWindow(DISPLAY, WinMessages);
  854. }
  855.  
  856.  
  857. void LibereMessageLine()
  858. {
  859.   int i;
  860.   for (i=0; i<NB_MESSAGES-1; i++) {
  861.     strcpy(Messages[i].mesg, Messages[i+1].mesg);
  862.     Messages[i].from_who=Messages[i+1].from_who; }
  863. }
  864.  
  865. void AfficheX(char *chaine, int who)
  866. {
  867.   static int i;
  868.   static GC gc;
  869.   
  870.   if (chaine!=NULL)  /* enregistrement du message */
  871.     {
  872.       LibereMessageLine();
  873.       strcpy(Messages[NB_MESSAGES-1].mesg, chaine);
  874.       Messages[NB_MESSAGES-1].from_who=who;
  875.     }
  876.   EffaceMessages();
  877.   for (i=0; i<NB_MESSAGES; i++)
  878.     {
  879.       if (Messages[i].from_who==-1)
  880.     gc=MiniLines_gc;
  881.       else
  882.     gc=Draw_gc[Messages[i].from_who];
  883.       XDrawString(DISPLAY, WinMessages, gc, MesgX, i*MESG_ECART+20, 
  884.           Messages[i].mesg, strlen(Messages[i].mesg));
  885.     }
  886. }
  887.  
  888. void Affiche(char *chaine)
  889. {
  890.   fprintf(stdout, chaine);
  891. }
  892.  
  893. void AffMessage(int FromWho, char *Message)
  894. {
  895.   char aff[MESSAGE_BUF];
  896.   
  897.   if (FromWho==-1)
  898.     sprintf(aff, "- From Server : %s", Message);
  899.   else if (FromWho>10) { /* 100, 200, 300, ... */ 
  900.     FromWho=FromWho/100-1;
  901.     sprintf(aff, "(%d)%s -> All : %s", FromWho, Names[FromWho], Message); }
  902.   else
  903.     sprintf(aff, "(%d)%s -> You : %s", FromWho, Names[FromWho], Message);
  904.   
  905.   AfficheX(aff, FromWho);
  906. }
  907.  
  908. /* -------------------------  interface X pour LOGIN ----------------------------- */
  909.  
  910. void DessineWaitWindow(int nbplayers, int nbinqueue)
  911. {
  912.   static char buf[100];
  913.  
  914.   XClearWindow(DISPLAY, WinWait);
  915.   sprintf(buf, "Game starts at %d players", nbplayers);
  916.   XDrawString(DISPLAY, WinWait, Login_gc, 20, 20, buf, strlen(buf));
  917.   sprintf(buf, "%d players are waiting", nbinqueue);
  918.   XDrawString(DISPLAY, WinWait, Login_gc, 20, 40, buf, strlen(buf));
  919.   XDrawLine(DISPLAY, WinWait, Login_gc, 0, 45, 200, 45);
  920.   sprintf(buf, "Hit Q to quit");
  921.   XDrawString(DISPLAY, WinWait, Login_gc, 60, 60, buf, strlen(buf));
  922. }
  923.  
  924.  
  925. void EffaceLigneLogin(int x, int y)
  926. {
  927.   XClearArea(DISPLAY, WinLogin, x, y-MESG_ECART, WIN_LOGIN_WIDTH, MESG_ECART+3, False);
  928. }
  929.  
  930. void AfficheTitre()
  931. {
  932.   char s1[]="AntipoliX", s2[]="AntipoliX - v2.0";
  933.   XDrawString(DISPLAY, WinLogin, Title_gc, 130, 80, s1, strlen(s1));
  934.   XDrawString(DISPLAY, WinLogin, Login_gc, 190, 105, s2, strlen(s2));
  935. }
  936.  
  937. void AfficheMotd()
  938. {
  939.   int i;
  940.  
  941.   XDrawLine(DISPLAY, WinLogin, Login_gc, 0, 400, WIN_LOGIN_WIDTH, 400);
  942.   for (i=0; i<nb_motd_lines; i++)
  943.     XDrawString(DISPLAY, WinLogin, Login_gc, 30, 420+17*i, Motd[i], strlen(Motd[i]));
  944.  
  945. }
  946.  
  947. void AfficheQueues()
  948. {
  949.   int i;
  950.   char QV[10];
  951.  
  952.   LargeurCase=WIN_LOGIN_WIDTH/(Max_Queues+1);
  953.   XDrawLine(DISPLAY, WinLogin, Login_gc, 0, 350, WIN_LOGIN_WIDTH, 350);
  954.   for (i=1; i<Max_Queues+1; i++)
  955.     XDrawLine(DISPLAY, WinLogin, Login_gc, i*LargeurCase, 350, i*LargeurCase, 400);
  956.   for (i=0; i<Max_Queues; i++)
  957.     {
  958.       sprintf(QV, "%d / %d", QueueWait[i], QueueGood[i]);
  959.       XDrawString(DISPLAY, WinLogin, Login_gc, i*LargeurCase+20, 380, QV, strlen(QV));
  960.     }
  961.   sprintf(QV, "QUIT");
  962.   XDrawString(DISPLAY, WinLogin, Login_gc, Max_Queues*LargeurCase+20, 380, QV, strlen(QV));
  963. }
  964.  
  965. void AfficheLoginInfo(char *info, int delai)
  966. {
  967.   XDrawString(DISPLAY, WinLogin, Login_gc, 50, 300, info, strlen(info));
  968.   XFlush(DISPLAY);
  969.   sleep(delai);
  970.   EffaceLigneLogin(50, 300);
  971. }
  972.  
  973. void AfficheQuitLogin()
  974. {
  975.   char buf[100];
  976.   sprintf(buf, "Click here to leave");
  977.   XDrawLine(DISPLAY, WinLogin, Login_gc, 0, 350, 500, 350);
  978.   XDrawString(DISPLAY, WinLogin, Login_gc, 100, 380, buf, strlen(buf));
  979. }
  980.  
  981. #define HIDE_MODE 0  /* pour le password */
  982. #define SHOW_MODE 1
  983.  
  984. void GetALoginString(int LineN, char *buf, char *buff, int x, int y, GC *gc, int Mode)
  985. {
  986.   int l0=strlen(buf), l=0, keyascii, i;
  987.   static XEvent Event;
  988.   
  989.   XDrawString(DISPLAY, WinLogin, *gc, x, y, buf, strlen(buf));
  990.   while (1)
  991.     {
  992.       if (XCheckMaskEvent(DISPLAY, KeyPressMask|ButtonPressMask|ExposureMask, &Event))
  993.     if (Event.type==ButtonPress && Event.xkey.y>350)
  994.       exit(0);
  995.     else if (Event.type==Expose)
  996.       {
  997.         AfficheTitre();
  998.         AfficheMotd();
  999.         for (i=0; i<LineN-1; i++)
  1000.           {
  1001.         EffaceLigneLogin(50, LOGIN_Y[i]);
  1002.         XDrawString(DISPLAY, WinLogin, *gc, 50, LOGIN_Y[i], M_buf[i], strlen(M_buf[i]));
  1003.           }
  1004.         EffaceLigneLogin(x, y);
  1005.         XDrawString(DISPLAY, WinLogin, *gc, x, y, buf, l0+(Mode&1)*l);
  1006.       }
  1007.     else if (Event.type==KeyPress)
  1008.       switch(keyascii=XLookupKeysym(&(Event.xkey), (Event.xkey.state & ShiftMask)))
  1009.         {
  1010.         case RETURN_KEY:
  1011.           {
  1012.         strcpy(buff, buf);
  1013.         strcpy(buf, buf+l0);
  1014.         return;
  1015.           }
  1016.         case BACK_SPACE:
  1017.         case DEL_KEY:
  1018.           if (l>0)
  1019.         l--;
  1020.           buf[l0+l]='\0';
  1021.           if (Mode!=HIDE_MODE)
  1022.         {
  1023.           EffaceLigneLogin(x, y);
  1024.           XDrawString(DISPLAY, WinLogin, *gc, x, y, buf, strlen(buf));
  1025.         }
  1026.           break;
  1027.         default:
  1028.           if (keyascii<_MAX_ASCII_ && keyascii>0)
  1029.         {
  1030.           buf[l0+l]=keyascii;
  1031.           l++;
  1032.           buf[l0+l]='\0';
  1033.           if (Mode!=HIDE_MODE)
  1034.             {
  1035.               EffaceLigneLogin(x, y);
  1036.               XDrawString(DISPLAY, WinLogin, *gc, x, y, buf, strlen(buf));
  1037.             }
  1038.         }
  1039.         }
  1040.     }
  1041. }
  1042.  
  1043. int ChooseQueue(int *nb_wanted)
  1044. {
  1045.   XEvent Event;
  1046.   int x, y, i, key_code;
  1047.  
  1048.   AfficheQueues();
  1049.   while (1)
  1050.     {
  1051.       if (XCheckMaskEvent(DISPLAY, KeyPressMask|ButtonPressMask|ExposureMask, &Event))
  1052.     switch(Event.type)
  1053.       {
  1054.       case Expose:
  1055.         AfficheTitre();
  1056.         AfficheMotd();
  1057.         for (i=0; i<2; i++)
  1058.           {
  1059.         EffaceLigneLogin(50, LOGIN_Y[i]);
  1060.         XDrawString(DISPLAY, WinLogin, Login_gc, 50, LOGIN_Y[i], M_buf[i], strlen(M_buf[i]));
  1061.           }
  1062.         AfficheQueues();
  1063.         break;
  1064.       case ButtonPress:
  1065.         x=Event.xbutton.x/LargeurCase;
  1066.         y=Event.xbutton.y;
  1067.         if (y>350 && y<400)
  1068.           {
  1069.         if (x>=Max_Queues)
  1070.           exit(0);
  1071.         else if (QueueGood[x]>0)
  1072.           return x;
  1073.           }
  1074.         break;
  1075.       case KeyPress:
  1076.         x=Event.xkey.x/LargeurCase;
  1077.         y=Event.xkey.y;
  1078.         if (y>350 && y<400 && x<Max_Queues)
  1079.           {
  1080.         key_code=XLookupKeysym(&(Event.xkey), 0)-_0_KEY;
  1081.         key_code=(key_code==0?10:key_code);      /* 0 <=> 10 */
  1082.         if (key_code>1 && key_code<11)
  1083.           {
  1084.             *nb_wanted=key_code;
  1085.             return x;
  1086.           }
  1087.           }
  1088.         break;
  1089.       }
  1090.     }
  1091. }
  1092.  
  1093. void EnterPlayerName(char *PlayerName)
  1094. {
  1095.   char buf[255];
  1096.   int M1x=50, M1y=LOGIN_Y[0];
  1097.   
  1098.   EffaceLigneLogin(M1x, M1y);
  1099.   EffaceLigneLogin(M1x, LOGIN_Y[1]);  /* au cas ou ce serait une deuxieme tentative */
  1100.   sprintf(buf, "Enter your name (%d Car. Max) : ", NAME_BUF);
  1101.   XDrawString(DISPLAY, WinLogin, Login_gc, M1x, M1y, buf, strlen(buf));
  1102.   GetALoginString(1, buf, M_buf[0], M1x, M1y, &Login_gc, SHOW_MODE);
  1103.  
  1104.   strncpy(PlayerName, buf, NAME_BUF);
  1105.   PlayerName[NAME_BUF-1]='\0';
  1106. }
  1107.  
  1108. void EnterPassword(char *Password)
  1109. {
  1110.   int M1x=50, M1y=LOGIN_Y[1];
  1111.   char buf[255];
  1112.  
  1113.   EffaceLigneLogin(M1x, M1y);
  1114.   sprintf(buf, "Enter your password : ");
  1115.   XDrawString(DISPLAY, WinLogin, Login_gc, M1x, M1y, buf, strlen(buf));
  1116.   GetALoginString(2, buf, M_buf[1], M1x, M1y, &Login_gc, HIDE_MODE);
  1117.   
  1118.   strncpy(Password, buf, PASSLENGTH);
  1119.   Password[PASSLENGTH-1]='\0';
  1120. }
  1121.  
  1122. void EnterEmail(char *Email)
  1123. {
  1124.   char buf[255];
  1125.   int M1x=50, M1y=LOGIN_Y[2];
  1126.  
  1127.   EffaceLigneLogin(M1x, M1y);
  1128.   sprintf(buf, "Enter your email : ");
  1129.   XDrawString(DISPLAY, WinLogin, Login_gc, M1x, M1y, buf, strlen(buf));
  1130.   GetALoginString(3, buf, M_buf[2], M1x, M1y, &Login_gc, SHOW_MODE);
  1131.   
  1132.   strncpy(Email, buf, EMAILENGTH);
  1133.   Email[EMAILENGTH-1]='\0';
  1134. }
  1135.  
  1136. int GetTimer(int sockfd)
  1137. {
  1138.   char buf[SABLIER_BUF];
  1139.   int sablier;
  1140.   
  1141.   Read(sockfd, buf, SABLIER_BUF);
  1142.   GetInt(buf, &sablier);
  1143.   
  1144.   return sablier;
  1145. }
  1146.  
  1147. void DrawUniverse(Univers *U)
  1148. {
  1149.   int p, i, j, real_p, real_x, real_y;
  1150.  
  1151.   CreationDesDamiers(U);
  1152.   CreationDesMiniPlx(U);
  1153.  
  1154.   for (p=CurrentPlx; p<CurrentPlx+NB_DAMIERS; p++)
  1155.     for (i=0; i<cut_nbx; i++)
  1156.       for (j=0; j<cut_nby; j++)
  1157.     /* on boucle sur les cases RELATIVES => on sait que l'on reste
  1158.        dans le domaine de ce qui peut etre affiche' a l'ecran */
  1159.     {
  1160.       View2Real(p, i, j, &real_p, &real_x, &real_y, CurrentMode);
  1161.       if (U->P[real_p].Case[real_x][real_y].Couleur>CASE_VIDE)
  1162.       FastDessinePiece(U->P[real_p].Case[real_x][real_y].Couleur, 
  1163.                U->P[real_p].Case[real_x][real_y].Type, 
  1164.                U->P[real_p].Case[real_x][real_y].Caract, real_p, real_x, real_y);
  1165.     }
  1166. }
  1167.  
  1168. int WhichCase(int x, int y, int *MemoP, int *MemoX, int *MemoY)
  1169. /* Recoit les coordonnees graphiques de la souris.
  1170.    Renvoie les coordonnees exactes de la case cliquee (independantes de View). */
  1171. {
  1172.   int p=0, Espace=LONG/2, Y=y, x2d, y2d, P, X2d, Y2d;
  1173.  
  1174.   while (Y-Espace>0 && p<NB_DAMIERS)
  1175.     {
  1176.       Y-=Espace;
  1177.       p++;
  1178.     }
  1179.   
  1180.   p=NB_DAMIERS-p-1;
  1181.   d3to2di(x-LEFT_BORDER, Espace-Y, &x2d, &y2d, COS_ALPHA[p], SIN_ALPHA[p]);
  1182.   
  1183.   if (x2d>=0 && x2d<cut_nbx && y2d>=0 && y2d<cut_nby)
  1184.     {
  1185.       View2Real(p+CurrentPlx, x2d, y2d, &P, &X2d, &Y2d, CurrentMode);
  1186.       *MemoP=P;
  1187.       *MemoX=X2d;
  1188.       *MemoY=Y2d;
  1189.       return 1;
  1190.     }
  1191.   return 0;
  1192. }
  1193.  
  1194.  
  1195. void SelectCase(int p, int x, int y)
  1196. /* recoit les coordonnees reelles de la case */
  1197. {
  1198.   DessineCase(p, x, y, &Selection_gc);
  1199. }
  1200.  
  1201.  
  1202. void AfficheMovement(Univers *U, int n)
  1203. {
  1204.   int i, j;
  1205.   
  1206.   for (i=0; i<Movement[n].nbcases; i++)
  1207.     SelectCase(Movement[n].cases[i].p, Movement[n].cases[i].x, Movement[n].cases[i].y);
  1208. }
  1209.  
  1210.  
  1211. void DeselectCase(Univers *U, int p, int cx, int cy)
  1212. /* recoit les coordonnees reelles de la case */
  1213. {
  1214.   int mid_x=cut_nbx/2, mid_y=cut_nby/2, rx, ry, rp;
  1215.   DessinePiece(U->P[p].Case[cx][cy].Couleur, U->P[p].Case[cx][cy].Type, 
  1216.            U->P[p].Case[cx][cy].Caract, p, cx, cy);
  1217.   DessineCase(p, cx, cy, &Lines_gc);
  1218.   Real2View(p, cx, cy, &rp, &rx, &ry, CurrentMode);
  1219.   if (rx==mid_x || rx==mid_x-1 || ry==mid_y || ry==mid_y-1)
  1220.     DessineMidLines(rp-CurrentPlx);
  1221.   AfficheMovement(U, CurrentMove);
  1222. }
  1223.  
  1224.  
  1225. int AddPiece(int Type, int Caract, int p, int x, int y, Univers *U)
  1226. /* recoit les coordonnees reelles de la case */
  1227. {
  1228.   int VChef=0, VFort=0;
  1229.   
  1230.   if (Caract==CHEF)
  1231.     {
  1232.       if (Chef==0 && Type!=CASE_VIDE)
  1233.     VChef=1;
  1234.       else if (Type!=CASE_VIDE)
  1235.     {
  1236.       AfficheX("You can place only one chief...", -1);
  1237.       return 0;
  1238.     }
  1239.     }
  1240.   else
  1241.     if (U->P[p].Case[x][y].Caract==CHEF)
  1242.       VChef=(-1);
  1243.   
  1244.   if (Type==FORTERESSE)
  1245.     if (U->P[p].Case[x][y].Type==FORTERESSE)
  1246.       VFort=0;
  1247.     else if (Forteresses < U->NbPlateaux)
  1248.       VFort=1;
  1249.     else
  1250.       {
  1251.     char m[100];
  1252.     sprintf(m, "You can't place more than %d fortresses", U->NbPlateaux);
  1253.     AfficheX(m, -1);
  1254.     return 0;
  1255.       }
  1256.   else
  1257.     if (U->P[p].Case[x][y].Type==FORTERESSE)
  1258.       VFort=(-1);
  1259.  
  1260.   Old_Chef=Chef;
  1261.   Old_Forteresses=Forteresses;
  1262.   Chef+=VChef;
  1263.   Forteresses+=VFort;
  1264.   
  1265.   return 1;
  1266. }
  1267.  
  1268. void DisplayPlayers()
  1269. {
  1270.   static char buf[100];
  1271.   int cpt=0, i;
  1272.  
  1273.   XClearWindow(DISPLAY, WinPlayers);
  1274.   strcpy(buf, "Still alive :");
  1275.   XDrawString(DISPLAY, WinPlayers, MiniLines_gc, 10, 15, buf, strlen(buf));
  1276.   for (i=0; i<nbplayers; i++)
  1277.     if (IsAlive[i])
  1278.       {
  1279.     sprintf(buf, "(%d) %s [%s] : %d", i, Names[i], Email[i], Score[i]);
  1280.     XDrawString(DISPLAY, WinPlayers, Draw_gc[i], 10, cpt*20+40, buf, strlen(buf));
  1281.     cpt++;
  1282.       }
  1283. }
  1284.  
  1285.  
  1286. void DisplayUniverseParameters(Parameters *p)
  1287. {
  1288.   printf("\nServer parameters :\n");
  1289.   printf("-------------------\n");
  1290.   printf("\nSIZE : %dx%dx%d\n\n", p->SIZE_Z, p->SIZE_X, p->SIZE_X);
  1291.   printf("Types:                Cost       Force          Moves\n");
  1292.   printf("a - Armie               %d          %d              %d\n", 
  1293.      p->COST_ARMIE, p->ATT_ARMIE, p->MOV_ARMIE);
  1294.   printf("h - Hovercraft          %d          %d              %d\n", 
  1295.      p->COST_HOVERCRAFT, p->ATT_HOVERCRAFT, p->MOV_HOVERCRAFT);
  1296.   printf("f - Fortress           %d          %d(def)         %d\n", 
  1297.      p->COST_FORTRESS, p->DEF_FORTRESS, 0);
  1298.  
  1299.   printf("\nCaracteristics:\n");
  1300.   printf("n - Normal\n");
  1301.   printf("i - Invisible           %d\n", p->COST_INVISIBILITY);
  1302.   printf("t - Teleporter          %d                        %d\n", 
  1303.      p->COST_TELEPORT, p->TELEPORT_FIELD);
  1304.   printf("c - Chief (unique)\n\n");
  1305. }
  1306.  
  1307.  
  1308. void ChooseStartPositions(Univers *U, int number, int Pecule)
  1309. {
  1310.   int CONTINUE=1, MemoP, MemoX, MemoY, IsSelected=0, IsOK, MemoExpose=0, MoveAngle=0;
  1311.   XEvent Event;
  1312.   Window w;
  1313.   int NextType, NextCaract;
  1314.  
  1315.   MiseAJourDuSablier(Pecule);
  1316.   while (CONTINUE)
  1317.     {
  1318.       if (!XCheckMaskEvent(DISPLAY, KeyPressMask|ButtonPressMask|
  1319.               ButtonReleaseMask|ExposureMask, &Event))
  1320.     MemoExpose=0;
  1321.       else if ((w=Event.xany.window)==WinPlayers)
  1322.     {
  1323.       if (Event.type==Expose)
  1324.         DisplayPlayers(); 
  1325.     }
  1326.       else if (w==WinMessages)
  1327.     {
  1328.       if (Event.type==Expose)
  1329.         {
  1330.           XGetWindowAttributes(DISPLAY, WinMessages, &XAttr);
  1331.           NB_MESSAGES=XAttr.height/MESG_ECART-1;
  1332.           ReallocMessagesTable(NB_MESSAGES);
  1333.           AfficheX(NULL, -1);
  1334.         }
  1335.     }
  1336.       else if (w==WinPlx)
  1337.     {
  1338.       switch(Event.type)
  1339.         {
  1340.         case Expose:
  1341.           if (!MemoExpose)
  1342.         {
  1343.           MemoExpose=1;
  1344.           DrawUniverse(U);
  1345.           MiseAJourDuSablier(Pecule);
  1346.           AfficheLegendeSablier("Credits");
  1347.           AfficheX(NULL, -1);
  1348.         }
  1349.           break;
  1350.         case ButtonPress:
  1351.           if (MoveAngle)
  1352.         {
  1353.           MoveAngle=0;
  1354.           InitCoords();
  1355.         }
  1356.           if (WhichCase(Event.xbutton.x, Event.xbutton.y, &MemoP, &MemoX, &MemoY))
  1357.         {
  1358.           if (U->P[MemoP].Case[MemoX][MemoY].Couleur!=-1)
  1359.             {
  1360.               IsSelected=1;
  1361.               SelectCase(MemoP, MemoX, MemoY);
  1362.               NextType=U->P[MemoP].Case[MemoX][MemoY].Type;
  1363.               NextCaract=U->P[MemoP].Case[MemoX][MemoY].Caract;
  1364.             }
  1365.         }
  1366.           break;
  1367.         case ButtonRelease:
  1368.           if (IsSelected)
  1369.         {
  1370.           IsSelected=0;
  1371.           IsOK=AddPiece(NextType, NextCaract, MemoP, MemoX, MemoY, U);
  1372.           if (IsOK)
  1373.             {
  1374.               if (!Place(U, MemoP, MemoX, MemoY, number, NextType, NextCaract, 
  1375.                  &Pecule, &c_params))
  1376.             {
  1377.               Chef=Old_Chef;
  1378.               Forteresses=Old_Forteresses;
  1379.             }
  1380.               MiseAJourDuSablier(Pecule);
  1381.             }
  1382.           DeselectCase(U, MemoP, MemoX, MemoY);
  1383.         }
  1384.           break;
  1385.         case KeyPress:
  1386.           switch(XLookupKeysym(&(Event.xkey), 0))
  1387.         {
  1388.         case FLECHE_H:
  1389.           if (Event.xkey.state & ControlMask)
  1390.             {
  1391.               if (ALPHA>0.1)  
  1392.             {
  1393.               ALPHA-=0.05;
  1394.               MoveAngle=1;
  1395.               CalculeCosSin();
  1396.               InitCoords();
  1397.               DrawUniverse(U);
  1398.             }
  1399.             }
  1400.           else
  1401.             if (CurrentPlx+NB_DAMIERS<cut_nbp)
  1402.               {
  1403.             CurrentPlx++;
  1404.             DrawUniverse(U);
  1405.               }
  1406.           break;
  1407.         case FLECHE_B:
  1408.           if (Event.xkey.state & ControlMask)
  1409.             {
  1410.               if (ALPHA<1.5)
  1411.             {
  1412.               ALPHA+=0.05;
  1413.               MoveAngle=1;
  1414.               CalculeCosSin();
  1415.               InitCoords();
  1416.               DrawUniverse(U);
  1417.             }
  1418.             }
  1419.           else
  1420.             if (CurrentPlx>0)
  1421.               {
  1422.             CurrentPlx--;
  1423.             DrawUniverse(U);
  1424.               }
  1425.           break;
  1426.         case FLECHE_G:
  1427.           CurrentView--;
  1428.           if (CurrentView<0)
  1429.             CurrentView=3;
  1430.           InitCutVars(CurrentMode);
  1431.           DrawUniverse(U);
  1432.           break;
  1433.         case FLECHE_D:
  1434.           CurrentView++;
  1435.           if (CurrentView>3)
  1436.             CurrentView=0;
  1437.           InitCutVars(CurrentMode);
  1438.           DrawUniverse(U);
  1439.           break;
  1440.         case V_KEY:
  1441.           CurrentPlx=0;
  1442.           CurrentMode++;
  1443.           if (CurrentMode>2)
  1444.             CurrentMode=0;
  1445.           InitCutVars(CurrentMode);
  1446.           DrawUniverse(U);
  1447.           break;
  1448.         case A_KEY:
  1449.           if (IsSelected)
  1450.             {
  1451.               NextType=ARMEE;
  1452.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1453.               SelectCase(MemoP, MemoX, MemoY);
  1454.             }
  1455.           break;
  1456.         case H_KEY:
  1457.           if (IsSelected)
  1458.             {
  1459.               NextType=HOVERCRAFT;
  1460.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1461.               SelectCase(MemoP, MemoX, MemoY);
  1462.             }
  1463.           break;
  1464.         case F_KEY:
  1465.           if (IsSelected)
  1466.             {
  1467.               NextType=FORTERESSE;
  1468.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1469.               SelectCase(MemoP, MemoX, MemoY);
  1470.             }
  1471.           break;
  1472.         case I_KEY:
  1473.           if (IsSelected)
  1474.             {
  1475.               NextCaract=INVISIBLE;
  1476.               if (NextType>CASE_VIDE)
  1477.             {
  1478.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1479.               SelectCase(MemoP, MemoX, MemoY);
  1480.             }
  1481.             }
  1482.           break;
  1483.         case T_KEY:
  1484.           if (IsSelected)
  1485.             {
  1486.               NextCaract=TELEPORT;
  1487.               if (NextType>CASE_VIDE)
  1488.             {
  1489.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1490.               SelectCase(MemoP, MemoX, MemoY);
  1491.             }
  1492.             }
  1493.           break;
  1494.         case C_KEY:
  1495.           if (IsSelected)
  1496.             {
  1497.               NextCaract=CHEF;
  1498.               if (NextType>CASE_VIDE)
  1499.             {
  1500.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1501.               SelectCase(MemoP, MemoX, MemoY);
  1502.             }
  1503.             }
  1504.           break;
  1505.         case N_KEY:
  1506.           if (IsSelected)
  1507.             {
  1508.               NextCaract=NORMAL;
  1509.               if (NextType>CASE_VIDE)
  1510.             {
  1511.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1512.               SelectCase(MemoP, MemoX, MemoY);
  1513.             }
  1514.             }
  1515.           break;
  1516.         case SPACE_KEY:
  1517.           if (IsSelected)
  1518.             {
  1519.               NextType=CASE_VIDE;
  1520.               NextCaract=NORMAL;
  1521.               DessinePiece(number, NextType, NextCaract, MemoP, MemoX, MemoY);
  1522.               SelectCase(MemoP, MemoX, MemoY);
  1523.             }
  1524.           break;
  1525.         case RETURN_KEY:
  1526.           if (Chef==0)
  1527.             AfficheX("You have to place your chief...", -1);
  1528.           else
  1529.             CONTINUE=0; /* les pieces sont placees : on envoie la position au serveur... */
  1530.           break;
  1531.         default:
  1532.           break;
  1533.         }
  1534.           break;
  1535.         default:
  1536.           MemoExpose=0;
  1537.           break;
  1538.         }
  1539.     }
  1540.     }
  1541. }
  1542.       
  1543. void InitMoves()
  1544. {
  1545.   int i;
  1546.   for (i=0; i<NB_MOVES; i++)
  1547.     {
  1548.       Movement[i].nbcases=0;
  1549.       Movement[i].cases=malloc(sizeof(Case));
  1550.     }
  1551. }
  1552.  
  1553.  
  1554. void AddThisCase(int Move, int p, int x, int y)
  1555. {
  1556.   Movement[Move].nbcases++;
  1557.   Movement[Move].cases=realloc(Movement[Move].cases, Movement[Move].nbcases * sizeof(Case));
  1558.   Movement[Move].cases[Movement[Move].nbcases-1].p=p;
  1559.   Movement[Move].cases[Movement[Move].nbcases-1].x=x;
  1560.   Movement[Move].cases[Movement[Move].nbcases-1].y=y;
  1561. }
  1562.   
  1563. void DelThisCase(int Move, int n)
  1564. {
  1565.   int i;
  1566.   for (i=0; i<Movement[Move].nbcases-1; i++)
  1567.     if (i<n)
  1568.       continue;
  1569.     else
  1570.       {
  1571.     Movement[Move].cases[i].p=Movement[Move].cases[i+1].p;
  1572.     Movement[Move].cases[i].x=Movement[Move].cases[i+1].x;
  1573.     Movement[Move].cases[i].y=Movement[Move].cases[i+1].y;
  1574.       }
  1575.   Movement[Move].nbcases--;
  1576.   Movement[Move].cases=realloc(Movement[Move].cases, Movement[Move].nbcases * sizeof(Case));
  1577. }
  1578.  
  1579.  
  1580. void ManageThisCase(Univers *U, int p, int x, int y, int Move, int joueur)
  1581. {
  1582.   int i, myarmies=0, ennemies=0, vides=0, IsOK=0;
  1583.   for (i=0; i<Movement[Move].nbcases && !EqualCase(Movement[Move].cases[i], p, x, y); i++)
  1584.     {
  1585.       Case c=Movement[Move].cases[i];
  1586.       int r=IsWhom(U, c.p, c.x, c.y, joueur);
  1587.       if (r==CASE_VIDE)
  1588.     vides++;
  1589.       else if (r==MYARMIE)
  1590.     myarmies++;
  1591.       else if (r==ENNEMY)
  1592.     ennemies++;
  1593.       else
  1594.     StopError(5678);
  1595.     }
  1596.   if (i<Movement[Move].nbcases) /* on a clique sur une case deja selectionnee */
  1597.     {
  1598.       DelThisCase(Move, i);
  1599.       DeselectCase(U, p, x, y);
  1600.     }
  1601.   else /* la case n'a pas encore ete selectionnee */
  1602.     {
  1603.       switch(IsWhom(U, p, x, y, joueur))
  1604.     {
  1605.     case CASE_VIDE:
  1606.       if (myarmies==1 && ennemies==0 && vides==0)
  1607.         IsOK=1;
  1608.       break;
  1609.     case MYARMIE:
  1610.       if (!(vides==1 && myarmies==1))
  1611.         IsOK=1;
  1612.       break;
  1613.     case ENNEMY:
  1614.       if (ennemies==0 && vides==0)
  1615.         IsOK=1;
  1616.       break;
  1617.     }
  1618.       if (IsOK && IsUnique(Movement, 0, 0, p, x, y))
  1619.     {
  1620.       AddThisCase(Move, p, x, y);
  1621.       SelectCase(p, x, y);
  1622.     }
  1623.     }
  1624. }
  1625.  
  1626.  
  1627. int AnalyseMessage(int FromWho, char *Message)
  1628. {
  1629.   int i, j;
  1630.   
  1631.   if (FromWho==-1) /* Message du serveur */
  1632.     {
  1633.       GetInt(Message, &i);
  1634.       GetInt(Message+szi, &j);
  1635.       if (i==KILLED || i==ABANDON || i==TIMEDEATH || i==DATAERROR)
  1636.     {
  1637.       IsAlive[j]=0;
  1638.       return 1;
  1639.     }
  1640.     }
  1641.   return 0;
  1642. }
  1643.  
  1644. void BeginTheGameClient(int sockfd)
  1645. {
  1646.   char buf[QUEUE_BUF], Message[MESSAGE_BUF];
  1647.   int i, mesg, Sablier, Who, IsMyTurn, Pecule, MemoExpose=0, MoveAngle=0, position;
  1648.   int NBPLX, NbCarEntree=0, MessageSendMode=0, DecalagePrompt, FirstStopMessage=1;
  1649.   Univers U;
  1650.   XEvent Event;
  1651.   Window w;
  1652.   int MemoP, MemoX, MemoY, MovesCptr=1, keyascii;
  1653.   
  1654.   Read(sockfd, buf, SABLIER_BUF);
  1655.   GetInt(buf, &Sablier);        /* on recoit la valeur de depart du sablier */
  1656.  
  1657.   for (i=0; i<nbplayers; i++) {    /* on recoit les NOMS des protagonistes */
  1658.     Read(sockfd, Names[i], NAME_BUF);
  1659.     IsAlive[i]=1; }
  1660.   
  1661.   for (i=0; i<nbplayers; i++)      /* on recoit les EMAILS des protagonistes */
  1662.     Read(sockfd, Email[i], EMAILENGTH);
  1663.  
  1664.   for (i=0; i<nbplayers; i++) {    /* on recoit les SCORES des protagonistes */
  1665.     Read(sockfd, buf, ENTIER_BUF);
  1666.     GetInt(buf, &Score[i]); }
  1667.  
  1668.   Affiche("\nWait please...\n");
  1669.  
  1670.   /* Attente du message "CHOOSE" ------------------------------ */
  1671.   Read(sockfd, buf, QUEUE_BUF);
  1672.   GetInt(buf, &Pecule);         /* on recoit la valeur du pecule au passage... */
  1673.   GetInt(buf+szi, &position);     /* ...et celle de la position du joueur */
  1674.  
  1675.   NBPLX=c_params.SIZE_Z;
  1676.   XUnmapWindow(DISPLAY, WinLogin);
  1677.   CreationDesFenetres(NBPLX);
  1678.   CreationDesGC(NBPLX);
  1679.  
  1680.   CreateUniverse(&U, NBPLX, c_params.SIZE_X);  /* pour malloquer .... */
  1681.   
  1682.   sleep(2);  /* bidouille... pour pas planter le lancement des fenetres X */
  1683.  
  1684.   if (GetEntete(sockfd)!=UNIVERS)  /* on lit l'entete... meme si on sait ce qui arrive ! */
  1685.     StopError(4);
  1686.  
  1687.   GetUniverse(sockfd, &U);
  1688.   DrawUniverse(&U);
  1689.   DisplayPlayers();
  1690.  
  1691.   AfficheLegendeSablier("Credits");
  1692.   AfficheX("Place your pieces, please...", -1);
  1693.   sprintf(Message, "Initial Credits : %d", Pecule);
  1694.   AfficheX(Message, -1);
  1695.   
  1696.   ChooseStartPositions(&U, position, Pecule);
  1697.   SendUniverse(sockfd, &U);
  1698.   AfficheX("Start position send", -1);
  1699.   AfficheLegendeSablier(" Time ");
  1700.  
  1701.   /* ---------------------------------------------------------
  1702.      ------------------ Begining of GAME ---------------------
  1703.      --------------------------------------------------------- */
  1704.  
  1705.   /* On attend plusieurs types de donnees :
  1706.      - Des messages d'autres joueurs
  1707.      - Des mises a jour du sablier
  1708.      - Des Univers
  1709.      _ Des invitations a jouer */
  1710.  
  1711.   IsMyTurn=0;
  1712.   while(1)
  1713.     {
  1714.       if (WaitForThisSocket(sockfd, 0) && FirstStopMessage)
  1715.     {
  1716.       switch(GetEntete(sockfd))
  1717.         {
  1718.         case MESSAGE:
  1719.           GetMessage(sockfd, &Who, Message);
  1720.           if (!AnalyseMessage(Who, Message))
  1721.         AffMessage(Who, Message);
  1722.           break;
  1723.         case SABLIER:
  1724.           Sablier=GetTimer(sockfd);
  1725.           MiseAJourDuSablier(Sablier);
  1726.           break;
  1727.         case UNIVERS:
  1728.           GetUniverse(sockfd, &U);
  1729.           DrawUniverse(&U);
  1730.           break;
  1731.         case MY_TURN:
  1732.           printf("\7");fflush(stdout);
  1733.           MovesCptr++;
  1734.           IsMyTurn=1;
  1735.           InitMoves();
  1736.           CurrentMove=0;
  1737.           AfficheMovement(&U, CurrentMove); 
  1738.           break;
  1739.         default:  /* en particulier "DEBLOCK" */
  1740.           if (FirstStopMessage) {
  1741.         AfficheX("Connection closed by server", -1);
  1742.         FirstStopMessage=0; }
  1743.           break;
  1744.         }
  1745.     }
  1746.  
  1747.       if (XCheckMaskEvent(DISPLAY, KeyPressMask|ButtonPressMask|ExposureMask, &Event)) {
  1748.     if ((w=Event.xany.window)==WinPlayers)
  1749.       {
  1750.         MemoExpose=0;
  1751.         if (Event.type==Expose)
  1752.           DisplayPlayers(); 
  1753.       }
  1754.     else if (w==WinMessages)
  1755.       {
  1756.         MemoExpose=0;
  1757.         if (Event.type==Expose)
  1758.           {
  1759.         XGetWindowAttributes(DISPLAY, WinMessages, &XAttr);
  1760.         NB_MESSAGES=XAttr.height/MESG_ECART-1;
  1761.         ReallocMessagesTable(NB_MESSAGES);
  1762.         AfficheX(NULL, -1);
  1763.           }
  1764.       }
  1765.     else if (w==WinPlx)
  1766.       {
  1767.         switch(Event.type)
  1768.           {
  1769.           case Expose:
  1770.         if (!MemoExpose)
  1771.           {
  1772.             MemoExpose=1;
  1773.             DrawUniverse(&U);
  1774.             AfficheMovement(&U, CurrentMove);
  1775.             MiseAJourDuSablier(Sablier);
  1776.             AfficheLegendeSablier(" Time ");
  1777.             AfficheX(NULL, -1);
  1778.           }
  1779.         break;
  1780.           case ButtonPress:
  1781.         WhichCase(Event.xbutton.x, Event.xbutton.y, &MemoP, &MemoX, &MemoY);
  1782.         if (MemoP>=0)
  1783.           ManageThisCase(&U, MemoP, MemoX, MemoY, CurrentMove, position);
  1784.         break;
  1785.           case KeyPress:
  1786.         keyascii=XLookupKeysym(&(Event.xkey), (Event.xkey.state & ShiftMask));
  1787.         if (MessageSendMode)
  1788.           {
  1789.             if (keyascii==RETURN_KEY)
  1790.               {
  1791.             MessageSendMode=0;
  1792.             strcpy(Message, Messages[NB_MESSAGES-1].mesg+DecalagePrompt);
  1793.             Message[strlen(Message)-1]='\0';
  1794.             strcpy(Messages[NB_MESSAGES-1].mesg+DecalagePrompt-1, Message);
  1795.             SendMessage(sockfd, Message, Who);
  1796.             AfficheX(NULL, -1);
  1797.               }
  1798.             else
  1799.               {
  1800.             if (keyascii==BACK_SPACE || keyascii==DEL_KEY) {
  1801.               if (NbCarEntree>0)
  1802.                 NbCarEntree--; }
  1803.             else if (keyascii<_MAX_ASCII_ && keyascii>0)
  1804.               {
  1805.                 Messages[NB_MESSAGES-1].mesg[DecalagePrompt+NbCarEntree]=keyascii;
  1806.                 NbCarEntree++;
  1807.               }
  1808.             Messages[NB_MESSAGES-1].mesg[DecalagePrompt+NbCarEntree]='>';
  1809.             Messages[NB_MESSAGES-1].mesg[DecalagePrompt+NbCarEntree+1]='\0';
  1810.             AfficheX(NULL, -1);
  1811.               }
  1812.           }
  1813.         else 
  1814.           switch(keyascii)
  1815.             {
  1816.             case FLECHE_H:
  1817.               if (Event.xkey.state & ControlMask)
  1818.             {
  1819.               if (ALPHA>0.1)  
  1820.                 {
  1821.                   ALPHA-=0.05;
  1822.                   MoveAngle=1;
  1823.                   CalculeCosSin();
  1824.                   InitCoords();
  1825.                   DrawUniverse(&U);
  1826.                   AfficheMovement(&U, CurrentMove);
  1827.                 }
  1828.             }
  1829.               else
  1830.             if (CurrentPlx+NB_DAMIERS<cut_nbp)
  1831.               {
  1832.                 CurrentPlx++;
  1833.                 DrawUniverse(&U);
  1834.                 AfficheMovement(&U, CurrentMove);
  1835.               }
  1836.               break;
  1837.             case FLECHE_B:
  1838.               if (Event.xkey.state & ControlMask)
  1839.             {
  1840.               if (ALPHA<1.5)
  1841.                 {
  1842.                   ALPHA+=0.05;
  1843.                   MoveAngle=1;
  1844.                   CalculeCosSin();
  1845.                   InitCoords();
  1846.                   DrawUniverse(&U);
  1847.                   AfficheMovement(&U, CurrentMove);
  1848.                 }
  1849.             }
  1850.               else
  1851.             if (CurrentPlx>0)
  1852.               {
  1853.                 CurrentPlx--;
  1854.                 DrawUniverse(&U);
  1855.                 AfficheMovement(&U, CurrentMove);
  1856.               }
  1857.               break;
  1858.             case FLECHE_G:
  1859.               CurrentView--;
  1860.               if (CurrentView<0)
  1861.             CurrentView=3;
  1862.               InitCutVars(CurrentMode);
  1863.               DrawUniverse(&U);
  1864.               AfficheMovement(&U, CurrentMove);
  1865.               break;
  1866.             case FLECHE_D:
  1867.               CurrentView++;
  1868.               if (CurrentView>3)
  1869.             CurrentView=0;
  1870.               InitCutVars(CurrentMode);
  1871.               DrawUniverse(&U);
  1872.               AfficheMovement(&U, CurrentMove);
  1873.               break;
  1874.             case V_KEY:
  1875.               CurrentPlx=0;
  1876.               CurrentMode++;
  1877.               if (CurrentMode>2)
  1878.             CurrentMode=0;
  1879.               InitCutVars(CurrentMode);
  1880.               DrawUniverse(&U);
  1881.               AfficheMovement(&U, CurrentMove);      
  1882.               break;
  1883.             case M_KEY:
  1884.             case A_KEY:
  1885.             case _0_KEY:
  1886.             case _1_KEY:
  1887.             case _2_KEY:
  1888.             case _3_KEY:
  1889.             case _4_KEY:
  1890.             case _5_KEY:
  1891.             case _6_KEY:
  1892.             case _7_KEY:
  1893.             case _8_KEY:
  1894.             case _9_KEY:
  1895.               MessageSendMode=1;
  1896.               NbCarEntree=0;
  1897.               LibereMessageLine();
  1898.               if (keyascii==M_KEY) {
  1899.             Who=(-1);
  1900.             sprintf(Messages[NB_MESSAGES-1].mesg, "%d -> (server) <>", position); }
  1901.               else if (keyascii==A_KEY) {
  1902.             Who=(-2);
  1903.             sprintf(Messages[NB_MESSAGES-1].mesg, "%d -> (all) <>", position); }
  1904.               else {
  1905.               Who=keyascii-_0_KEY;
  1906.               sprintf(Messages[NB_MESSAGES-1].mesg, "%d -> %d <>", position, Who); }
  1907.               Messages[NB_MESSAGES-1].from_who=(-1);
  1908.               DecalagePrompt=strlen(Messages[NB_MESSAGES-1].mesg)-1;
  1909.               AfficheX(NULL, -1);
  1910.               break;
  1911.             case R_KEY: /* reset du movement en cours */
  1912.               Movement[CurrentMove].nbcases=0;
  1913.               DrawUniverse(&U);
  1914.               break;
  1915.             case RETURN_KEY:
  1916.               if (IsMyTurn)
  1917.             {
  1918.               IsMyTurn=0;
  1919.               SendMovement(sockfd, Movement);
  1920.               sprintf(Message, "Movement #%d send", MovesCptr-1);
  1921.               AfficheX(Message, -1);
  1922.             }
  1923.               break;
  1924.             } /* ---- fin du "case KeyPress:" ----- */
  1925.         break;
  1926.           default:
  1927.         MemoExpose=0;
  1928.           }
  1929.       }
  1930.       }
  1931.       else
  1932.     MemoExpose=0;
  1933.     }
  1934. }
  1935.  
  1936.  
  1937. void SendName(int sockfd, char *PlayerName)
  1938. {
  1939.   int i, j;
  1940.   char buf[szi], Password[PASSLENGTH], Verif[PASSLENGTH];
  1941.   
  1942.   while (1)
  1943.     {
  1944.       EnterPlayerName(PlayerName);
  1945.       write(sockfd, PlayerName, NAME_BUF); /* envoi du NOM du joueur */
  1946.       if (!strncmp(PlayerName, "God", 4))
  1947.     exit(0);
  1948.       CliRead(sockfd, buf, szi, TIMEOUT2, ConnectionClosed);
  1949.       GetInt(buf, &i);
  1950.       if (i==1234) /* le nom existe bien */
  1951.     {
  1952.       EnterPassword(Password);
  1953.       write(sockfd, Password, PASSLENGTH);
  1954.       CliRead(sockfd, buf, szi, TIMEOUT2, ConnectionClosed);
  1955.       GetInt(buf, &j);
  1956.       if (j==5678)  /* password OK */
  1957.         return;
  1958.       AfficheLoginInfo("Bad password...", 1);
  1959.     }
  1960.       else if (i==2345)  /* le nom n'existe pas */
  1961.     {
  1962.       AfficheLoginInfo("This is a new character...", 1);
  1963.       EnterPassword(Password);
  1964.       AfficheLoginInfo("Verification : enter your password again", 1);
  1965.       EnterPassword(Verif);
  1966.       if (!strncmp(Password, Verif, PASSLENGTH))
  1967.         {
  1968.           PutInt(buf, 8765);  /* ok, password entre' */
  1969.           write(sockfd, buf, szi);
  1970.           write(sockfd, Password, PASSLENGTH);
  1971.           return;
  1972.         }
  1973.       else
  1974.         {
  1975.           AfficheLoginInfo("Passwords do not match !", 1);
  1976.           PutInt(buf, 4321);  /* probleme de password... on recommence... */
  1977.           write(sockfd, buf, szi);
  1978.         }
  1979.     }
  1980.       else
  1981.     StopError(1345);
  1982.     }
  1983. }
  1984.  
  1985.  
  1986. void ReceiveMotd(int sockfd)
  1987. {
  1988.   char buf[ENTIER_BUF];
  1989.   int i;
  1990.  
  1991.   Read(sockfd, buf, ENTIER_BUF);
  1992.   GetInt(buf, &nb_motd_lines);
  1993.  
  1994.   for (i=0; i<nb_motd_lines; i++)
  1995.     Read(sockfd, Motd[i], MESSAGE_BUF);
  1996. }
  1997.  
  1998. void ReceiveQueueValues(int sockfd)
  1999. {
  2000.   char buf[ENTIER_BUF];
  2001.   int i;
  2002.   
  2003.   Read(sockfd, buf, ENTIER_BUF);
  2004.   GetInt(buf, &Max_Queues);
  2005.   
  2006.   for (i=0; i<Max_Queues; i++)
  2007.     {
  2008.       Read(sockfd, buf, ENTIER_BUF);
  2009.       GetInt(buf, &QueueWait[i]);
  2010.       Read(sockfd, buf, ENTIER_BUF);
  2011.       GetInt(buf, &QueueGood[i]);
  2012.     }
  2013. }
  2014.  
  2015. void ReceiveUniverseParameters(int sockfd, Parameters *p)
  2016. {
  2017.   char buf[ENTIER_BUF];
  2018.  
  2019.   Read(sockfd, buf, ENTIER_BUF);
  2020.   GetInt(buf, &(p->TIME));
  2021.   Read(sockfd, buf, ENTIER_BUF);
  2022.   GetInt(buf, &(p->CREDITS_100));
  2023.   Read(sockfd, buf, ENTIER_BUF);
  2024.   GetInt(buf, &(p->SIZE_X));
  2025.   Read(sockfd, buf, ENTIER_BUF);
  2026.   GetInt(buf, &(p->SIZE_Z));
  2027.   Read(sockfd, buf, ENTIER_BUF);
  2028.   GetInt(buf, &(p->COST_FORTRESS));
  2029.   Read(sockfd, buf, ENTIER_BUF);
  2030.   GetInt(buf, &(p->COST_ARMIE));
  2031.   Read(sockfd, buf, ENTIER_BUF);
  2032.   GetInt(buf, &(p->COST_HOVERCRAFT));
  2033.   Read(sockfd, buf, ENTIER_BUF);
  2034.   GetInt(buf, &(p->COST_INVISIBILITY));
  2035.   Read(sockfd, buf, ENTIER_BUF);
  2036.   GetInt(buf, &(p->COST_TELEPORT));
  2037.   Read(sockfd, buf, ENTIER_BUF);
  2038.   GetInt(buf, &(p->DEF_FORTRESS));
  2039.   Read(sockfd, buf, ENTIER_BUF);
  2040.   GetInt(buf, &(p->DEF_ARMIE));
  2041.   Read(sockfd, buf, ENTIER_BUF);
  2042.   GetInt(buf, &(p->DEF_HOVERCRAFT));
  2043.   Read(sockfd, buf, ENTIER_BUF);
  2044.   GetInt(buf, &(p->ATT_ARMIE));
  2045.   Read(sockfd, buf, ENTIER_BUF);
  2046.   GetInt(buf, &(p->ATT_HOVERCRAFT));
  2047.   Read(sockfd, buf, ENTIER_BUF);
  2048.   GetInt(buf, &(p->MOV_ARMIE));
  2049.   Read(sockfd, buf, ENTIER_BUF);
  2050.   GetInt(buf, &(p->MOV_HOVERCRAFT));
  2051.   Read(sockfd, buf, ENTIER_BUF);
  2052.   GetInt(buf, &(p->TELEPORT_FIELD));
  2053. }
  2054.  
  2055.  
  2056. void main(int argc, char *argv[])
  2057. {
  2058.   struct hostent *Host;
  2059.   struct sockaddr_in servaddr;
  2060.   int sockfd, PORTN, NbInQueue, wanted_queue, nb_wanted;
  2061.   char buf[QUEUE_BUF], PlayerName[NAME_BUF], Email[EMAILENGTH];
  2062.  
  2063.   if (argc!=3 && argc!=4)
  2064.     {
  2065.       fprintf(stderr, "Usage : client <host> <port>\n");
  2066.       exit(0);
  2067.     }
  2068.   
  2069.   if ((Host=gethostbyname(argv[1]))==NULL)
  2070.     {
  2071.       fprintf(stderr, "** unknown host %s\n", argv[1]);
  2072.       exit(0);
  2073.     }
  2074.  
  2075.   PORTN=atoi(argv[2]);
  2076.  
  2077.   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  2078.     {
  2079.       fprintf(stderr, "** socket error **\n");
  2080.       exit(0);
  2081.     }
  2082.   
  2083.   fprintf(stdout, "Calling %s on port %d.\n", argv[1], PORTN);
  2084.   bzero(&servaddr, sizeof(servaddr));
  2085.   bcopy(*(Host->h_addr_list), (char *)&servaddr.sin_addr.s_addr, 4);
  2086.   servaddr.sin_port = PORTN;
  2087.   servaddr.sin_family=AF_INET;
  2088.  
  2089.   if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))<0)
  2090.     {
  2091.       fprintf(stderr, "** Unable to connect to server\n");
  2092.       exit(0);
  2093.     }
  2094.   fprintf(stdout, "Got connection with AntipoliX.\nWait please...");
  2095.   
  2096.   ReceiveUniverseParameters(sockfd, &c_params);
  2097.   ReceiveMotd(sockfd);
  2098.   ReceiveQueueValues(sockfd);
  2099.   DisplayUniverseParameters(&c_params);
  2100.  
  2101.   InitVariables();
  2102.   LoginWindowCreation();
  2103.   Login_gc=CreeGC(WinLogin, "wheat1", 1);
  2104.   Title_gc=CreeTitleGC(WinLogin, "wheat3");
  2105.   AfficheTitre();
  2106.   AfficheMotd();
  2107.  
  2108.   SendName(sockfd, PlayerName);
  2109.   EnterEmail(Email);
  2110.   write(sockfd, Email, EMAILENGTH);
  2111.  
  2112.   wanted_queue=ChooseQueue(&nb_wanted);
  2113.   PutInt(buf, wanted_queue);
  2114.   write(sockfd, buf, ENTIER_BUF); /* ENVOI du desir du client */
  2115.   PutInt(buf, nb_wanted);
  2116.   write(sockfd, buf, ENTIER_BUF);
  2117.  
  2118.   CliRead(sockfd, buf, QUEUE_BUF, TIMEOUT2, ConnectionError);
  2119.   GetInt(buf, &nbplayers);
  2120.  
  2121.   if (nbplayers>=0)
  2122.     {
  2123.       XEvent Event;
  2124.       XUnmapWindow(DISPLAY, WinLogin);
  2125.       
  2126.       GetInt(buf+szi, &NbInQueue);
  2127.       if (NbInQueue!=nbplayers)
  2128.     XMapWindow(DISPLAY, WinWait);
  2129.       Login_gc=CreeGC(WinWait, "wheat1", 1);
  2130.       DessineWaitWindow(nbplayers, NbInQueue);
  2131.       XFlush(DISPLAY);
  2132.       while (NbInQueue<nbplayers)
  2133.     {
  2134.       if (XCheckMaskEvent(DISPLAY, KeyPressMask|ButtonPressMask|ExposureMask, &Event))
  2135.         {
  2136.           if (Event.type==Expose)
  2137.         {
  2138.           DessineWaitWindow(nbplayers, NbInQueue);
  2139.           XFlush(DISPLAY);
  2140.         }
  2141.           else if (Event.type==KeyPress && 
  2142.                XLookupKeysym(&(Event.xkey), (Event.xkey.state & ShiftMask))==BigQ_KEY)
  2143.         exit(0);
  2144.         }
  2145.       if (WaitForThisSocket(sockfd, 0))
  2146.         {
  2147.           Read(sockfd, buf, ENTIER_BUF);
  2148.           GetInt(buf, &NbInQueue);
  2149.           DessineWaitWindow(nbplayers, NbInQueue);
  2150.           XFlush(DISPLAY);
  2151.         }
  2152.       if (NbInQueue==nbplayers)
  2153.         XUnmapWindow(DISPLAY, WinWait);
  2154.     }
  2155.     }
  2156.   else
  2157.     {
  2158.       fprintf(stderr, "No space left for this game. Try later.\n");
  2159.       exit(0);
  2160.     }
  2161.  
  2162.   XFlush(DISPLAY);
  2163.   BeginTheGameClient(sockfd);
  2164.   
  2165. }
  2166.